package health_system.health_system.service;


import health_system.health_system.dto.PageResponseDTO;
import health_system.health_system.dto.UserCreateDTO;
import health_system.health_system.dto.UserDTO;
import health_system.health_system.dto.UserUpdateDTO;
import health_system.health_system.entity.User;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

/**
 * Service interface for managing users
 */
public interface UserService {

    /**
     * Get the ID of the currently logged-in user
     * 
     * @return the current user's ID
     */
    default Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.isAuthenticated()) {
            User user = (User) authentication.getPrincipal();
            return user.getId();
        }
        throw new IllegalStateException("No authenticated user found");
    }

    /**
     * Create a new user
     * 
     * @param createDTO the user creation data
     * @return the created user DTO
     */
    UserDTO createUser(UserCreateDTO createDTO);
    
    /**
     * Update an existing user
     * 
     * @param id the user id
     * @param updateDTO the user update data
     * @return the updated user DTO
     */
    UserDTO updateUser(Long id, UserUpdateDTO updateDTO);
    
    /**
     * Get a user by id
     * 
     * @param id the user id
     * @return the user DTO
     */
    UserDTO getUserById(Long id);
    
    /**
     * Get a user entity by id
     * 
     * @param id the user id
     * @return the user entity
     */
    User getUserEntityById(Long id);
    
    /**
     * Find a user entity by id
     * 
     * @param id the user id
     * @return optional user entity
     */
    Optional<User> findUserEntityById(Long id);
    
    /**
     * Get a user by username
     * 
     * @param username the user username
     * @return the user DTO
     */
    UserDTO getUserByUsername(String username);
    
    /**
     * Get a user by email
     * 
     * @param email the user email
     * @return the user DTO
     */
    UserDTO getUserByEmail(String email);
    
    /**
     * Get a user by phone number
     * 
     * @param phoneNumber the user phone number
     * @return the user DTO
     */
    UserDTO getUserByPhoneNumber(String phoneNumber);
    
    /**
     * Delete a user by id (soft delete)
     * 
     * @param id the user id
     */
    void deleteUser(Long id);
    
    /**
     * Get all users
     * 
     * @return list of user DTOs
     */
    List<UserDTO> getAllUsers();
    
    /**
     * Get paginated list of users
     * 
     * @param pageable pagination information
     * @return paginated user DTOs
     */
    PageResponseDTO<UserDTO> getAllUsers(Pageable pageable);
    
    /**
     * Search users by keyword (name or username)
     * 
     * @param keyword the search keyword
     * @return list of user DTOs matching search criteria
     */
    List<UserDTO> searchUsers(String keyword);
    
    /**
     * Get paginated search results of users by keyword
     * 
     * @param keyword the search keyword
     * @param pageable pagination information
     * @return paginated user DTOs matching search criteria
     */
    PageResponseDTO<UserDTO> searchUsers(String keyword, Pageable pageable);
    
    /**
     * Check if a user exists by username
     * 
     * @param username the username to check
     * @return true if exists, false otherwise
     */
    boolean existsByUsername(String username);
    
    /**
     * Check if a user exists by email
     * 
     * @param email the email to check
     * @return true if exists, false otherwise
     */
    boolean existsByEmail(String email);
    
    /**
     * Check if a user exists by phone number
     * 
     * @param phoneNumber the phone number to check
     * @return true if exists, false otherwise
     */
    boolean existsByPhoneNumber(String phoneNumber);
    
    /**
     * Get all non-deleted users
     * 
     * @return list of active user DTOs
     */
    List<UserDTO> getActiveUsers();
    
    /**
     * Change user password
     * 
     * @param id the user id
     * @param currentPassword the current password
     * @param newPassword the new password
     * @return the updated user DTO
     */
    UserDTO changePassword(Long id, String currentPassword, String newPassword);
    
    /**
     * Update user avatar
     * 
     * @param id the user id
     * @param avatarUrl the new avatar URL
     * @return the updated user DTO
     */
    UserDTO updateAvatar(Long id, String avatarUrl);
    
    /**
     * Update user profile information
     * 
     * @param id the user id
     * @param fullName the full name
     * @param bio the biography
     * @param dateOfBirth the date of birth
     * @return the updated user DTO
     */
    UserDTO updateProfile(Long id, String fullName, String bio, LocalDate dateOfBirth);
    
    /**
     * Update user contact information
     *
     * @param id the user id
     * @param email the email
     * @param phoneNumber the phone number
     * @return the updated user DTO
     */
    UserDTO updateContactInfo(Long id, String email, String phoneNumber);
} 